package com.zm;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * Hello world!
 *
 */
public class App 
{
    public static void main( String[] args ) throws
            InstantiationException,//构造函数执行错误
            IllegalAccessException,//错误访问 例如：调用private方法
            NoSuchFieldException,//没有该属性
            NoSuchMethodException,//没有该方法
            InvocationTargetException {//方法执行异常
        System.out.println("********************** A ********************************");
        Class<A> aClass = A.class;
        for (Field field : aClass.getFields()) {
            System.out.println("field.getName() = " + field.getName());
        }
        System.out.println("---------------------");
        for (Field field : aClass.getDeclaredFields()) {
            System.out.println("field.getName() = " + field.getName());
        }
        System.out.println("=============================================");
        for (Method method : aClass.getMethods()) {
            System.out.println("method.getName() = " + method.getName());
        }
        System.out.println("---------------------");
        for (Method method : aClass.getDeclaredMethods()) {
            System.out.println("method.getName() = " + method.getName());
        }

        System.out.println("********************** B ********************************");
        Class<B> bClass = B.class;
        for (Field field : bClass.getFields()) {
            System.out.println("field.getName() = " + field.getName());
        }
        System.out.println("---------------------");
        for (Field field : bClass.getDeclaredFields()) {
            System.out.println("field.getName() = " + field.getName());
        }
        System.out.println("=============================================");
        for (Method method : bClass.getMethods()) {
            System.out.println("method.getName() = " + method.getName());
        }
        System.out.println("---------------------");
        for (Method method : bClass.getDeclaredMethods()) {
            System.out.println("method.getName() = " + method.getName());
        }

        System.out.println("********************** C ********************************");
        Class<C> cClass = C.class;
        for (Field field : cClass.getFields()) {
            System.out.println("field.getName() = " + field.getName());
        }
        System.out.println("---------------------");
        for (Field field : cClass.getDeclaredFields()) {
            System.out.println("field.getName() = " + field.getName());
        }
        System.out.println("=============================================");
        for (Method method : cClass.getMethods()) {
            System.out.println("method.getName() = " + method.getName());
        }
        System.out.println("---------------------");
        for (Method method : cClass.getDeclaredMethods()) {
            System.out.println("method.getName() = " + method.getName());
        }


        System.out.println("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&");

        C c = cClass.newInstance();
        Class _Class = c.getClass();
        while (_Class!=null){
            Field[] fields = _Class.getDeclaredFields();
            for (Field field : fields) {
                System.out.println("field.getName() = " + field.getName());
            }
            _Class = _Class.getSuperclass();
        }
        System.out.println("---------------------------");
        _Class = c.getClass();
        while (_Class!=null){
            Method[] methods = _Class.getDeclaredMethods();
            for (Method method : methods) {
                System.out.println("method.getName() = " + method.getName());
            }
            _Class = _Class.getSuperclass();
        }
        System.out.println("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&");
        A a = aClass.newInstance();
        Field field = aClass.getDeclaredField("A");
        field.setAccessible(true);
        field.set(a,"你好");
        System.out.println("field.get(a) = " + field.get(a));

        Method method = aClass.getDeclaredMethod("hello_A", String.class);
        method.setAccessible(true);
        method.invoke(a,"zhangming");

    }
}

class A{
    public int a;
    private String A;

    public void hello_a(){
        System.out.println("helloa");
    }

    private String hello_A(String name){
        System.out.println("hello:"+name);
        return "ok";
    }

}

class B extends A{
    public int b;
    private String B;

    public void hello_b(){
        System.out.println("hello:b");
    }

    private String hello_B(String name){
        System.out.println("hello:"+name);
        return "ok";
    }
}

class C extends B{
    public int c;
    private String C;

    public void hello_c(){
        System.out.println("hello:c");
    }

    private String hello_C(String name){
        System.out.println("hello:"+name);
        return "ok";
    }
}
